import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:smart/db/hi_cache.dart';
import 'package:smart/http/dao/login_dao.dart';
import 'package:smart/navigator/bottom_navigator.dart';
import 'package:smart/navigator/hi_navigator.dart';
import 'package:smart/page/login_page.dart';
import 'package:smart/page/registration_page.dart';
import 'package:smart/page/video_detail_page.dart';
import 'package:smart/provider/hi_provider.dart';
import 'package:smart/provider/theme_provider.dart';
import 'package:smart/util/toast.dart';

import 'model/video_model.dart';

void main() {
  //runApp(const MyApp());
//  runApp(const RegistrationPage());
  // runApp(const LoginPage());
  runApp(const BiliApp());
}

class BiliApp extends StatefulWidget {
  const BiliApp({super.key});

  @override
  State<BiliApp> createState() => _BiliAppState();
}

class _BiliAppState extends State<BiliApp> {
  BiliRouteDelegate _routeDelegate = BiliRouteDelegate();
/*  BiliRouteInformationParser _routeInformationParser =
      BiliRouteInformationParser();*/

  @override
  Widget build(BuildContext context) {
    /* return FutureBuilder<HiCache>(
        //进行初始化
        future: HiCache.preInit(),
        builder: (BuildContext context, AsyncSnapshot<HiCache> snapshot) {
          var widget = snapshot.connectionState == ConnectionState.done
              ? Router(
                  routerDelegate: _routeDelegate,
                )
              : Scaffold(
                  body: Center(child: CircularProgressIndicator()),
                );

          return MaterialApp(
            home: widget,
            theme: ThemeData(primarySwatch: white),
          );
        });*/
    return FutureBuilder<HiCache>(
        //进行初始化
        future: HiCache.preInit(),
        builder: (BuildContext context, AsyncSnapshot<HiCache> snapshot) {

          //定义route
          var widget;

          if (snapshot.connectionState == ConnectionState.waiting) {
            // 当Future还未完成时，显示加载中的UI
            widget=  Center(child: CircularProgressIndicator());
            print('ConnectionState.waiting  progress');
          } else if (snapshot.hasError) {
            // 当Future发生错误时，显示错误提示的UI
            print('ConnectionState  hasError');
            widget=  Center(child: CircularProgressIndicator());
          } else if(snapshot.connectionState == ConnectionState.done) {
            // 当Future成功完成时，显示数据
            print('ConnectionState  当Future成功完成时');
            widget=  Router(routerDelegate: _routeDelegate);
          }

     /*     //定义route
          var widget = snapshot.connectionState == ConnectionState.done
              ? Router(routerDelegate: _routeDelegate)
              : Scaffold(
                  body: Center(child: CircularProgressIndicator()),
                );*/

          return MultiProvider(
              providers: topProviders,
              child: Consumer<ThemeProvider>(
                  builder: (BuildContext context, // Consumer 读取provider 一种方式
                      ThemeProvider themeProvider,
                      Widget? child) {
                return MaterialApp(
                    home: widget,
                    theme: themeProvider.getTheme(),
                    darkTheme: themeProvider.getTheme(),
                    /*themeMode: themeProvider.getThemeMode()*/);
              }));
        });
  }
}

//创建一个代理
/*
基本知识充电：with=》Dart 实现类似多继承的方式 用with
ChangeNotifier:就是个监听器，Dart 中的观察者模式:作用便是做事件通知
PopNavigatorRouterDelegateMixin:它的主要作用是响应 Android 设备的回退按钮
GlobalKey 是用来做状态管理的

 */
class BiliRouteDelegate extends RouterDelegate<BiliRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<BiliRoutePath> {
  final GlobalKey<NavigatorState> navigatorKey;
  RouteStatus _routeStatus = RouteStatus.home;
  List<MaterialPage> pages = [];
  VideoModel? videoModel;

  // 为Navigator 设置一个key，必要的时候可以通过navigatorKey.currentState来获取到NavigatorState 对象。
  BiliRouteDelegate() : navigatorKey = GlobalKey<NavigatorState>() {
    //实现录音偶跳转逻辑
    HiNavigator.getInstance().registerRouteJump(
        RouteJumpListener(onJumpTo: (RouteStatus routeStatus, {Map? args}) {
      _routeStatus = routeStatus;
      if (routeStatus == RouteStatus.detail) {
        this.videoModel = args!['videoMo'];
      }
      notifyListeners();
    }));
  }

  @override
  Widget build(BuildContext context) {
    var index = getPageIndex(pages, routeStatus);
    List<MaterialPage> tempPages = pages;
    if (index != -1) {
      // 要打开的页面在栈中已经存在，则将该页面和它上面的所有页面进行出栈
      // tips 具体规则可以根据需要进行调整，这里要求栈中只允许有一个同样的页面实例
      print('build index:$index');
      tempPages = tempPages.sublist(0, index);
    }
    var page;
    if (routeStatus == RouteStatus.home) {
      //跳转首页时，将栈中的其它页面进行出栈，因为首页不可回退
      print('build routeStatus  home');
      pages.clear();
      /*   page = pageWrap(HomePage(
        onJumpToDetail: (videoModel) {
          print('HomePage onJumpToDetail');
          this.videoModel = videoModel;
          notifyListeners();
        },
      ));*/
      //page = pageWrap(HomePage());
      page = pageWrap(BottomNavigator());
    } else if (routeStatus == RouteStatus.detail) {
      print('build routeStatus  detail');
      page = pageWrap(VideoDetailPage(videoModel!!));
    } else if (routeStatus == RouteStatus.registration) {
      print('build registration  ');
      page = pageWrap(RegistrationPage());
    } else if (routeStatus == RouteStatus.login) {
      print('build login  detail');
      page = pageWrap(LoginPage());
    }
    //重新创建一个数组，否则pages 因引用没有改变路由不会生效:  组合一次函数
    tempPages = [...tempPages, page];

    // 打开新页面的时候 通知路由发生变化
    HiNavigator.getInstance().notify(tempPages, pages);
    pages = tempPages;

    /*  //  管理路由堆栈
    pages = [
      pageWrap(HomePage(
        onJumpToDetail: (videoModel) {
          this.videoModel = videoModel;
          notifyListeners();
        },
      )),
      if (videoModel != null) pageWrap(VideoDetailPage(videoModel!))
    ];
*/
    return WillPopScope(
      // fix Android 物理返回按键，无返回上一页问题
      //fix Android物理返回键，无法返回上一页问题@https://github.com/flutter/flutter/issues/66349
      onWillPop: () async =>
          !(await navigatorKey.currentState?.maybePop() ?? false),
      child: Navigator(
        key: navigatorKey,
        pages: pages,
        onPopPage: (route, result) {
          //登录页未登录进行拦截
          if (route.settings is MaterialPage) {
            //登录页未登录 返回拦截
            if ((route.settings as MaterialPage).child is LoginPage) {
              // 测试用  if ((route.settings as MaterialPage).child is RegistrationPage) {
              if (!hasLogin) {
                showWarnToast('请先登录!');
                return false;
              }
            }
          }
          //是否可以返回上一页
          if (!route.didPop(result)) {
            //比如表单判断 参数不对；首页判断 不让返回需求效果
            return false;
          }

          var tempPages = [...pages];
          pages.removeLast();
          // 返回上一页的时候通知路由变化的变更
          HiNavigator.getInstance().notify(pages, tempPages);

          return true;
        },
      ),
    );
  }

  bool get hasLogin => LoginDao.getBoardingPass() != null;
  RouteStatus get routeStatus {
    if (_routeStatus != RouteStatus.registration && !hasLogin) {
      print('routeStatus  当前未登录状态  将状态设置为login');
      return _routeStatus = RouteStatus.login;
    } else if (videoModel != null) {
      print('routeStatus  videoModel != null  状态为视频详情页状态!');
      return _routeStatus = RouteStatus.detail;
    } else {
      print('route 其它状态  _routeStatus:${_routeStatus.name}');
      return _routeStatus;
    }
  }

  @override
  Future<void> setNewRoutePath(BiliRoutePath configuration) async {
    print('setNewRoutePath  目前暂不处理 ....');
  }
}

//定义路由数据， path   【创建的XXPath 类】
class BiliRoutePath {
  final String location;
  BiliRoutePath.home() : location = '/';
  BiliRoutePath.detail() : location = '/details';
  BiliRoutePath.login() : location = '/login';
  BiliRoutePath.registration() : location = '/registration';
}
//login, registration, home, detail, unknown }

/*
//创建页面
pageWrap(Widget child) {
  print('pageWrap');
  return MaterialPage(key: ValueKey(child.hashCode), child: child);
}
*/
